/*!
 * \file HftStraContext.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief HFT策略上下文实现文件
 * 
 * 本文件实现了HFT(High Frequency Trading)策略上下文类的核心功能，作为HFT策略与引擎之间的桥梁。
 * 负责处理引擎的各种高频交易事件回调，并将这些事件转发给具体的HFT策略实例。
 * 包括策略初始化、交易时段管理、Level2数据处理、订单管理、持仓跟踪和交易通道状态管理等功能。
 */
#include "HftStraContext.h"
#include "../Includes/HftStrategyDefs.h"

/**
 * @brief 构造函数
 * 
 * 创建HFT策略上下文实例，初始化基础上下文和策略指针
 * 
 * @param engine HFT引擎指针
 * @param name 策略名称
 * @param bAgent 是否为代理模式，默认为true
 */
HftStraContext::HftStraContext(WtHftEngine* engine, const char* name, bool bAgent /* = true */)
	: HftStraBaseCtx(engine, name, bAgent)
	, _strategy(NULL)
{
}

/**
 * @brief 析构函数
 * 
 * 清理资源
 */
HftStraContext::~HftStraContext()
{
}

/**
 * @brief 策略初始化回调实现
 * 
 * 当策略需要初始化时被调用，先调用基类初始化，再转发给具体的策略实例
 */
void HftStraContext::on_init()
{
	HftStraBaseCtx::on_init();

	if (_strategy)
		_strategy->on_init(this);
}

/**
 * @brief 交易时段开始回调实现
 * 
 * 当交易时段开始时被调用，先调用基类处理，再转发给具体的策略实例
 * 
 * @param uTDate 交易日期（格式：YYYYMMDD）
 */
void HftStraContext::on_session_begin(uint32_t uTDate)
{
	HftStraBaseCtx::on_session_begin(uTDate);

	if (_strategy)
		_strategy->on_session_begin(this, uTDate);
}

/**
 * @brief 交易时段结束回调实现
 * 
 * 当交易时段结束时被调用，先转发给具体的策略实例，再调用基类处理
 * 
 * @param uTDate 交易日期（格式：YYYYMMDD）
 */
void HftStraContext::on_session_end(uint32_t uTDate)
{
	if (_strategy)
		_strategy->on_session_end(this, uTDate);

	HftStraBaseCtx::on_session_end(uTDate);
}

/**
 * @brief Tick数据回调实现
 * 
 * 当有新的Tick数据时被调用，更新动态盈亏，检查订阅状态后转发给具体的策略实例
 * 
 * @param stdCode 标准合约代码
 * @param newTick 新的Tick数据
 */
void HftStraContext::on_tick(const char* stdCode, WTSTickData* newTick)
{
	// 更新动态盈亏
	update_dyn_profit(stdCode, newTick);

	// 检查是否订阅了该合约的Tick数据
	auto it = _tick_subs.find(stdCode);
	if (it != _tick_subs.end())
	{
		if (_strategy)
			_strategy->on_tick(this, stdCode, newTick);
	}

	HftStraBaseCtx::on_tick(stdCode, newTick);
}

/**
 * @brief 委托队列数据回调实现
 * 
 * 当有新的委托队列数据时被调用，转发给具体的策略实例
 * 
 * @param stdCode 标准合约代码
 * @param newOrdQue 新的委托队列数据
 */
void HftStraContext::on_order_queue(const char* stdCode, WTSOrdQueData* newOrdQue)
{
	if (_strategy)
		_strategy->on_order_queue(this, stdCode, newOrdQue);

	HftStraBaseCtx::on_order_queue(stdCode, newOrdQue);
}

/**
 * @brief 委托明细数据回调实现
 * 
 * 当有新的委托明细数据时被调用，转发给具体的策略实例
 * 
 * @param stdCode 标准合约代码
 * @param newOrdDtl 新的委托明细数据
 */
void HftStraContext::on_order_detail(const char* stdCode, WTSOrdDtlData* newOrdDtl)
{
	if (_strategy)
		_strategy->on_order_detail(this, stdCode, newOrdDtl);

	HftStraBaseCtx::on_order_detail(stdCode, newOrdDtl);
}

/**
 * @brief 成交明细数据回调实现
 * 
 * 当有新的成交明细数据时被调用，转发给具体的策略实例
 * 
 * @param stdCode 标准合约代码
 * @param newTrans 新的成交明细数据
 */
void HftStraContext::on_transaction(const char* stdCode, WTSTransData* newTrans)
{
	if (_strategy)
		_strategy->on_transaction(this, stdCode, newTrans);

	HftStraBaseCtx::on_transaction(stdCode, newTrans);
}

/**
 * @brief K线数据回调实现
 * 
 * 当有新的K线数据时被调用，转发给具体的策略实例
 * 
 * @param code 合约代码
 * @param period K线周期
 * @param times K线倍数
 * @param newBar 新的K线数据
 */
void HftStraContext::on_bar(const char* code, const char* period, uint32_t times, WTSBarStruct* newBar)
{
	if (_strategy)
		_strategy->on_bar(this, code, period, times, newBar);

	HftStraBaseCtx::on_bar(code, period, times, newBar);
}

/**
 * @brief 成交回报回调实现
 * 
 * 当有成交回报时被调用，转换为内部合约代码后转发给具体的策略实例
 * 
 * @param localid 本地订单ID
 * @param stdCode 标准合约代码
 * @param isBuy 是否为买入
 * @param vol 成交数量
 * @param price 成交价格
 */
void HftStraContext::on_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double price)
{
	const char* innerCode = get_inner_code(stdCode);
	if (_strategy)
		_strategy->on_trade(this, localid, innerCode, isBuy, vol, price, getOrderTag(localid));

	HftStraBaseCtx::on_trade(localid, innerCode, isBuy, vol, price);
}

/**
 * @brief 订单回报回调实现
 * 
 * 当有订单状态变化时被调用，转换为内部合约代码后转发给具体的策略实例
 * 
 * @param localid 本地订单ID
 * @param stdCode 标准合约代码
 * @param isBuy 是否为买入
 * @param totalQty 总数量
 * @param leftQty 剩余数量
 * @param price 委托价格
 * @param isCanceled 是否已撤销，默认为false
 */
void HftStraContext::on_order(uint32_t localid, const char* stdCode, bool isBuy, double totalQty, double leftQty, double price, bool isCanceled /* = false */)
{
	const char* innerCode = get_inner_code(stdCode);
	if (_strategy)
		_strategy->on_order(this, localid, innerCode, isBuy, totalQty, leftQty, price, isCanceled, getOrderTag(localid));

	HftStraBaseCtx::on_order(localid, innerCode, isBuy, totalQty, leftQty, price, isCanceled);
}

/**
 * @brief 持仓变化回调实现
 * 
 * 当持仓发生变化时被调用，转发给具体的策略实例
 * 
 * @param stdCode 标准合约代码
 * @param isLong 是否为多头持仓
 * @param prevol 变化前总持仓
 * @param preavail 变化前可用持仓
 * @param newvol 变化后总持仓
 * @param newavail 变化后可用持仓
 * @param tradingday 交易日
 */
void HftStraContext::on_position(const char* stdCode, bool isLong, double prevol, double preavail, double newvol, double newavail, uint32_t tradingday)
{
	if (_strategy)
		_strategy->on_position(this, stdCode, isLong, prevol, preavail, newvol, newavail);
}

/**
 * @brief 交易通道就绪回调实现
 * 
 * 当交易通道连接就绪时被调用，转发给具体的策略实例
 */
void HftStraContext::on_channel_ready()
{
	if (_strategy)
		_strategy->on_channel_ready(this);

	HftStraBaseCtx::on_channel_ready();
}

/**
 * @brief 交易通道断开回调实现
 * 
 * 当交易通道连接断开时被调用，转发给具体的策略实例
 */
void HftStraContext::on_channel_lost()
{
	if (_strategy)
		_strategy->on_channel_lost(this);

	HftStraBaseCtx::on_channel_lost();
}

/**
 * @brief 委托回报回调实现
 * 
 * 当有委托回报时被调用，转发给具体的策略实例
 * 
 * @param localid 本地订单ID
 * @param stdCode 标准合约代码
 * @param bSuccess 委托是否成功
 * @param message 回报消息
 */
void HftStraContext::on_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message)
{
	if (_strategy)
		_strategy->on_entrust(localid, bSuccess, message, getOrderTag(localid));

	HftStraBaseCtx::on_entrust(localid, get_inner_code(stdCode), bSuccess, message);
}